`define RESET 3'd0
`define LOAD_DIV_LOW 3'd1
`define LOAD_DIV_HIGH 3'd2
`define WAITING 3'd3
`define READING_DATA 3'd4
`define SENDING 3'd5

module processor(
	input clk, rst,
	inout [7:0] databus,
	input rda,
	input tbr,
	output iocs,
	output iorw,
	output [1:0] ioaddr,
	input [1:0] dipsw);

reg [2:0] status;
reg [7:0] dataToSend;
reg iorwTemp;
reg [1:0] ioaddrTemp;
always @(posedge clk) begin
	if(rst)
		status <= `LOAD_DIV_LOW; 
	else if(status == `LOAD_DIV_LOW) begin
		//set up the divisor		
		ioaddrTemp <= 2'b10;	//selects the division buffer low
		iorwTemp <= 1'b0;		//selects write
		if(dipsw == 2'b11) begin
			//20Mhz - 9600 baud - divisor = 129
			dataToSend <= 8'd129;
		end
		else if(dipsw == 2'b10) begin
			//20Mhz - 4800 baud - divisor = 259
			dataToSend <= 8'd3;
		end
		else if(dipsw == 2'b01) begin
			//5Mhz - 9600 baud - divisor = 32
			dataToSend <= 8'd32;
		end
		else if(dipsw == 2'b00) begin
			//5Mhz - 4800 baud - divisor = 64
			dataToSend <= 8'd64;
		end
		status <= `LOAD_DIV_HIGH;
	end
	else if(status == `LOAD_DIV_HIGH) begin
		//set up the divisor		
		ioaddrTemp <= 2'b11;	//selects the division buffer low
		iorwTemp <= 1'b0;		//selects write
		if(dipsw == 2'b10) begin
			//20Mhz - 4800 baud - high order bit = 1
			dataToSend <= 8'd1;
		end
		else begin
			//no high order bits in the divisor
			dataToSend <= 8'd0;
		end
		status <= `WAITING;
	end
	else if(status == `WAITING) begin
		if (rda) begin
			//setup signals to read from the receive buffer
			iorwTemp <= 1'b1;
			ioaddrTemp <= 2'b00;
			status <= `READING_DATA;
		end
		else	begin
			status <= `WAITING;
			iorwTemp <= 1'b0;
			ioaddrTemp <= 2'b01;
		end
	end
	else if (status == `READING_DATA) begin
		//save data
		dataToSend <= databus + 1;
		iorwTemp <= 1'b0;
		ioaddrTemp <= 2'b01;
		status <= `SENDING;
	end
	else if (status == `SENDING) begin
	   	//send data
		if (tbr) begin
			iorwTemp <= 1'b0;
			ioaddrTemp <= 2'b00;
			status <= `WAITING;
		end
	end

end

assign iocs = ~rst;
assign iorw = iorwTemp;
assign ioaddr = ioaddrTemp;
assign databus = ~iorw ? dataToSend : 8'dz;
endmodule
